package com.ssyan.principle.DependenceInversion.improve;

/**
 * @author ssyan
 * @Description 依赖传递的三种方式：
 *              1）通过接口传递实现依赖
 *              2）通过构造方法依赖传递
 *              3）通过setter方法传递
 * @create 2021/8/25 23:01
 * @Version 1.0
 */
public class DependencyPass {

    public static void main(String[] args) {
        //测试接口传递
        ChangHong changHong = new ChangHong();
//        OpenAndClose openAndClose = new OpenAndClose();
//        openAndClose.open(changHong);

        //测试构造方法传递依赖
//        OpenAndClose openAndClose = new OpenAndClose(changHong);
//        openAndClose.open();

        //测试setter方法传递依赖
        OpenAndClose openAndClose = new OpenAndClose();
        openAndClose.setTv(changHong);
        openAndClose.open();

    }
}

//ITV实例
class ChangHong implements ITV {

    @Override
    public void play() {
        System.out.println("长虹电视机，打开");
    }
}

//默认ITV实例
class DefaultTV implements ITV {

    @Override
    public void play() {
        System.out.println("请正确选择电视机");
    }
}

//方式一：通过接口传递实现依赖
//开关的接口
//interface IOpenAndClose {
//    public void open(ITV tv);//抽象方法，接收接口
//}
//
//interface ITV { //ITV接口
//    public void play();
//}
////实现接口
//class OpenAndClose implements IOpenAndClose {
//
//    @Override
//    public void open(ITV tv) {
//        tv.play();
//    }
//}

//方式二：通过构造方法依赖传递
//interface IOpenAndClose {
//    public void open(); //抽象方法
//}
//interface ITV { //ITV接口
//    public void play();
//}
//class OpenAndClose implements IOpenAndClose {
//    public ITV tv; //成员
//    public OpenAndClose(ITV tv) { //构造器
//        this.tv = tv;
//    }
//
//    @Override
//    public void open() {
//        this.tv.play();
//    }
//}

//方法三：通过setter方法传递
interface IOpenAndClose {
    public void open(); //抽象方法
    public void setTv(ITV tv);
}

interface ITV { //ITV接口
    public void play();
}

class OpenAndClose implements IOpenAndClose {
    private ITV tv;

    @Override
    public void open() {
        //调用默认实现类，避免空指针异常
        if (this.tv == null){
            DefaultTV defaultTV = new DefaultTV();
            this.tv = defaultTV;
        }
        this.tv.play();
    }

    @Override
    public void setTv(ITV tv) {
        this.tv = tv;
    }
}